#include "Sock.h"
Sock::Sock()
{
}
Sock::Sock(int sock) : sock_(sock)
{
}

int Sock::getSock()
{
    return sock_;
}
void Sock::cerateSocket()
{
    sock_ = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sock_ < 0)
    {
        // perror("socket() failed"); exit(-1);
        printf("%s:%s:%d listen socket create error:%d\n", __FILE__, __FUNCTION__, __LINE__, errno);
        exit(-1);
    }
}

void Sock::cerateNonBlockingSocket()
{
    sock_ = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP);
    if (sock_ < 0)
    {
        // perror("socket() failed"); exit(-1);
        printf("%s:%s:%d listen socket create error:%d\n", __FILE__, __FUNCTION__, __LINE__, errno);
        exit(-1);
    }
}
void Sock::setReuseAddr(bool flag)
{
    int opt = flag ? 1 : 0;
    ::setsockopt(sock_, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
}
void Sock::setReusePort(bool flag)
{
    int opt = flag ? 1 : 0;
    ::setsockopt(sock_, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt));
}
void Sock::settcpnodelay(bool flag)
{
    int opt = flag ? 1 : 0;
    ::setsockopt(sock_, SOL_SOCKET, TCP_NODELAY, &opt, sizeof(opt));
}
void Sock::setKeepAlive(bool flag)
{
    int opt = flag ? 1 : 0;
    ::setsockopt(sock_, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeof(opt));
}
void Sock::bind(const InetAddress &servaddr)
{
    // int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
    if (::bind(sock_, servaddr.addr(), sizeof(servaddr.getSockAddr_in())) < 0)
    {
        perror("bind() failed");
        close(sock_);
        exit(-1);
    }
}

void Sock::listen(int backlog )
{
    if (::listen(sock_, backlog) < 0)
    {
        perror("bind() failed");
        close(sock_);
        exit(-1);
    }
}
int Sock::Accept( InetAddress &clientaddr)
{
    // int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
    struct sockaddr_in peer;
    socklen_t len = sizeof(peer);
    int clientSock = accept(sock_, (struct sockaddr *)&peer, &len);
    clientaddr.setaddr(peer);
    return clientSock;
}

int Sock::acceptNonBlocking( InetAddress &clientaddr)
{
    // int accept4(int sockfd, struct sockaddr *addr,socklen_t *addrlen, int flags);
    struct sockaddr_in peer;
    socklen_t len = sizeof(peer);
    int clientSock = accept4(sock_, (struct sockaddr *)&peer, &len, SOCK_NONBLOCK);
    clientaddr.setaddr(peer);
    return clientSock;
}

Sock::~Sock()
{
    ::close(sock_);
}
